
#include <rtos.h>
#include <plc_rte.h>
#include <hwboard.h>
#include "ePaper.h"
#include "Holder.h"

ePaper *dev;
extern "C"
{
void epaper_drawString(int x, int y, const char *text, int size) {
    dev->drawString(const_cast<char *>(text), x, y, size);
}

void epaper_drawFloat(int x, int y, float *val, int dec, int size) {
    dev->drawFloat(val, dec, x, y, size);
}

void epaper_drawNumber(int x, int y, int val, int size) {
    dev->drawNumber(val, x, y, size);
}

void epaper_clear() {

    dev->clear(EPD_4IN01F_WHITE);
}

int ePaper::begin(uint32_t tick) {
#ifdef USE_FREERTOS
    lock = Rtos::SemaphoreCreate();
    Rtos::create_thread_run("ePaper", 2048, PriorityNormal, (void *) &thd_epaper, this);
#endif
    return 0;
}

int ePaper::drawString(char *string, int x, int y, int size) {
    int r = Paint_DrawString_EN(x, y, string, pFont, _color_bg, _color);
    return r;
}

int ePaper::drawFloat(float *pDouble, int point, int x, int y, int fontid) {
    char buf[32];
    snprintf(buf, 32, "%2.f", *pDouble);
    int r = Paint_DrawString_EN(x, y, buf, pFont, _color_bg, _color);
    return r;
}

int ePaper::drawNumber(int val, int x, int y, int fontid) {
    int r = Paint_DrawNum(x, y, val, pFont, _color_bg, _color);
    return r;
}

void ePaper::clear(int i) {
    Paint_NewImage(IMAGE_BW, EPD_4IN01F_WIDTH, EPD_4IN01F_HEIGHT, IMAGE_ROTATE_0, IMAGE_COLOR_POSITIVE);
    Paint_SetScale(7);
    Paint_Clear(i);
}

#include <display.h>
const display_abi display = {
        .clear = &epaper_clear,
        .string = &epaper_drawString,
        .number_double = &epaper_drawFloat,
        .number_int = &epaper_drawNumber};
}

void ePaper::thd_epaper(const void *arg) {
    uint32_t next_tick;
    auto *epd = (ePaper *) arg;
    while (true) {
        uint32_t tick = Rtos::ticks();
        epd->loop(tick);
        int cmd = Rtos::SemaphoreWait(epd->lock, rte_config.epaper_interval * 60 * 1000);
    }
}

int ePaper::run(uint32_t tick) {
    return 0;
}

int ePaper::loop(uint32_t tick) {
    // logger.debug("Draw black picture");
    rte.event(pb_event_epd_updated, false);
     rte_data.task_busy |= 1;
    if (DEV_Module_Init() != 0) {
        logger.error("ePaper module init failed");
    }
    logger.debug("e-Paper Init ...");
    EPD_4IN01F_Init();
    logger.debug("e-Paper Clear...");
    clear(EPD_4IN01F_WHITE);
    logger.debug("e-Paper Draw...");
    board.epaper_draw();
    logger.debug("e-Paper Display...");
    EPD_4IN01F_Display();
    logger.debug("e-Paper Delay %d...", rte_config.epaper_interval);
    logger.debug("e-Paper Delay exit...");
     rte_data.task_busy &= ~1;
    data.count++;
    rte.event(pb_event_epd_updated, true);
    return 0;
}

int ePaper::DrawTime(int x, int y, PAINT_TIME *ptr) {
    int r = Paint_DrawTime(x, y, ptr, pFont, _color_bg, _color, false);
    return r;
}

void ePaper::drawPixel(int x, int y, u8 color) {
    Paint_DrawPixel(x, y, color);
}

void ePaper::set_color(int color, u8 color_bg) {
    _color = color;
    _color_bg = color_bg;
}

void ePaper::drawLine(int x1, int y1, int x2, int y2) {
    Paint_DrawLine(x1, y1, x2, y2, _color, LINE_STYLE_SOLID, DOT_PIXEL_2X2);
}

void ePaper::forceUpdate() {
    Rtos::SemaphoreRelease(lock);
}

#ifdef __PLATFORMIO_BUILD_DEBUG__
int ePaper::dev_test(uint32_t tick)
{
    return 0;
}
#endif

int ePaper::diag(uint32_t tick) {
    return 0;
}

ePaper displayer;
